//////////////////////////////////////////////
// MeshInputLayout.h
//
//////////////////////////////////////////////

/// Defines / Macros -------------------------

#pragma once

/// Includes ---------------------------------

// nkGraphics
#include "../../Dll/DllDefines.h"

#include "MeshInputLayoutAttribute.h"

// nkMemory
#include <NilkinsMemory/Containers/BufferCast.h>
#include <NilkinsMemory/Containers/String.h>
#include <NilkinsMemory/Containers/StringView.h>

/// Class ------------------------------------

namespace nkGraphics
{
	class DLL_GRAPHICS_EXPORT MeshInputLayout final
	{
		public :

			// Constructor, destructor
			MeshInputLayout () noexcept ;

			// Getters
			unsigned long long getHash () const ;
			nkMemory::StringView getPositionAttributeName () const ;
			nkMemory::StringView getNormalAttributeName () const ;
			nkMemory::StringView getTexCoordAttributeName () const ;
			unsigned int getComputedAttributeOffset (nkMemory::StringView name) const ;

			// Setters
			void setAttribute (const MeshInputLayoutAttribute& attribute, unsigned int index) ;
			void setPositionAttributeName (nkMemory::StringView value) ;
			void setNormalAttributeName (nkMemory::StringView value) ;
			void setTexCoordAttributeName (nkMemory::StringView value) ;

			// Attribute management
			void addAttribute (const MeshInputLayoutAttribute& attribute) ;
			const MeshInputLayoutAttribute* getAttribute (unsigned int index) const ;
			const MeshInputLayoutAttribute* getAttribute (nkMemory::StringView name) const ;
			unsigned int getAttributeCount () const ;
			unsigned int getTotalDeclarationSlots () const ;
			void removeAttribute (unsigned int index) ;
			void removeAttribute (nkMemory::StringView name) ;
			bool hasAttribute (nkMemory::StringView name, unsigned int semanticIndex = 0u) const ;

			// Operators
			bool operator< (const MeshInputLayout& other) const ;
			bool operator== (const MeshInputLayout& other) const ;

		private :

			// Structures
			struct AttributeEntry final
			{
				unsigned long long _hash = 0ull ;
				MeshInputLayoutAttribute _attribute ;
			} ;

		private :

			// Functions
			// Hash
			void _recomputeHash () ;

		private :

			// Attributes
			// List of attributes inside
			nkMemory::BufferCast<AttributeEntry> _attributes ;

			// Annotations
			nkMemory::String _positionAttributeName ;
			nkMemory::String _normalAttributeName ;
			nkMemory::String _texCoordAttributeName ;

			// Full hash for quicker sorting and comparison
			unsigned long long _hash ;
	} ;
}